# 只需3行代码即可实现完整验证！
# from pydantic import BaseModel, Field
# class User(BaseModel):
#     name: str = Field(min_length=1, max_length=50)  # 内置字符串长度验证
#     age: int = Field(ge=0, le=150)  # 数值范围验证（类似Java的@Min/@Max）

# user = User(name = "小滴课堂", age = 100)
# print(user)


# from pydantic import BaseModel, Field
# class User(BaseModel):
#     # ... 表示必填字段
#     name: str = Field(..., title="用户名", min_length=2)
# # 正确用法
# user = User(name="Alice")

# # 错误用法：缺少 name 字段
# user = User()  # 触发 ValidationError

# from pydantic import BaseModel, Field

# class Config(BaseModel):
#     api_key: str = Field(...)  # 必填
#     timeout: int = Field(10, ge=1)  # 可选，默认 10，但必须 >=1

# # 正确
# config = Config(api_key="secret")
# assert config.timeout == 10

# # 错误：未传 api_key
# Config(timeout=5)  # 触发 ValidationError


# =====================field_validator====================
# from pydantic import BaseModel, ValidationError, field_validator,Field

# class User(BaseModel):
#     username: str

#     # 带默认值的可选字段
#     # int | None表示 age 变量的类型可以是整数 (int) 或 None，旧版本的写法：age: Union[int, None]
#     # Python 3.10 开始引入，替代了早期通过 Union[int, None] 的形式（仍兼容）
#     age: int | None = Field(
#         default=None,
#         ge=18,
#         description="用户年龄必须≥18岁"
#     )

#     @field_validator("username")
#     def validate_username(cls, value: str) -> str:
#         # cls: 模型类（可访问其他字段）
#         # value: 当前字段的值
#         if len(value) < 3:
#             raise ValueError("用户名至少 3 个字符")
#         return value  # 可修改返回值（如格式化）

# user = User(username="steven", age=100)
# print(user)


# from langchain_core.prompts import ChatPromptTemplate
# from langchain_openai import ChatOpenAI
# from pydantic import BaseModel, Field
# from langchain_core.output_parsers import PydanticOutputParser
# # 定义模型
# model = ChatOpenAI(
#     model_name="qwen-plus",
#     base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
#     api_key="sk-005c3c25f6d042848b29d75f2f020f08",
#     temperature=0.7
# )

# # Step1: 定义Pydantic模型


# class UserInfo(BaseModel):
#     name: str = Field(description="用户姓名")
#     age: int = Field(description="用户年龄", gt=0)
#     hobbies: list[str] = Field(description="兴趣爱好列表")


# # Step2: 创建解析器
# parser = PydanticOutputParser(pydantic_object=UserInfo)

# # Step3: 构建提示模板

# prompt = ChatPromptTemplate.from_template("""
# 提取用户信息，严格按格式输出：
# {format_instructions}

# 输入内容：
# {input}
# """)

# # 注入格式指令
# prompt = prompt.partial(
#     format_instructions=parser.get_format_instructions()
# )

# # Step4: 组合处理链
# chain = prompt | model | parser


# # 执行解析
# result = chain.invoke({
#     "input": """
#    我的名称是张三，年龄是18岁，兴趣爱好有打篮球、看电影。
#    """
# })

# print(type(result))
# print(result)


from langchain_openai import ChatOpenAI
from pydantic import BaseModel, Field
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import JsonOutputParser
# 定义模型
model = ChatOpenAI(
    model_name="qwen-plus",
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
    api_key="sk-005c3c25f6d042848b29d75f2f020f08",
    temperature=0.7
)

# 定义JSON结构


class SentimentResult(BaseModel):
    sentiment: str
    confidence: float
    keywords: list[str]


# 构建处理链
parser = JsonOutputParser(pydantic_object=SentimentResult)

prompt = ChatPromptTemplate.from_template("""  
分析评论情感：  
{input}  
按以下JSON格式返回：  
{format_instructions}  
""").partial(format_instructions=parser.get_format_instructions())

chain = prompt | model | parser

# 执行分析
result = chain.invoke({"input": "物流很慢，包装破损严重"})
print(result)

# 输出：
# {
#   "sentiment": "negative",
#   "confidence": 0.85,
#   "keywords": ["物流快", "包装破损"]
# }


# 2. 执行流式调用
# for chunk in chain.stream({"input": "物流很慢，包装破损严重"}):
#    print(chunk)  # 逐词输出
